package com.he.heblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.he.heblog.dto.ArticleDto;
import com.he.heblog.dto.ChildListDto;
import com.he.heblog.dto.CommentDto;
import com.he.heblog.dto.UserDto;
import com.he.heblog.entity.*;
import com.he.heblog.mapper.ArticleMapper;
import com.he.heblog.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 余生
 * @since 2023-03-27
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
    @Autowired
    ArticletypeService articletypeService;
    @Autowired
    UserService userService;
    @Autowired
    TagService tagService;
    @Autowired
    CommentService commentService;
    @Autowired
    ChildcommentService childcommentService;
    @Autowired
    SupportService supportService;
    @Autowired
    ChildlistService childlistService;
    @Override
    public Page<ArticleDto> getArticleListExtra(Integer page, Integer pageSize,Integer articleType) {

        QueryWrapper<Article> articleQueryWrapper = new QueryWrapper<>();
        articleQueryWrapper.eq(articleType!=null,"articleType",articleType);
        Page<Article> objectPage = new Page<>(page, pageSize);
        Page<Article> page1 = this.page(objectPage,articleQueryWrapper);
//  文章所属用户信息，文章的评论数，文章对应的标签，文章当前用户是否点赞
        Page<ArticleDto> articleDtoPage = new Page<ArticleDto>();
// 复制除了记录外的所有信息
        BeanUtils.copyProperties(page1,articleDtoPage);
//   对article的分页记录进行处理
        List<Article> records = page1.getRecords();
        ArrayList<ArticleDto> dtoArrayList = new ArrayList<>();
//        判断当前是否登录
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        for(Article article:records){

// 新建文章传输对象
            ArticleDto articleDto = new ArticleDto();
//        将原有信息保存到文章传输对象中
            BeanUtils.copyProperties(article,articleDto);
//查询文章中的用户ID对应的用户信息
            Integer userid = article.getUserid();
            User byId = userService.getById(userid);
//        只传输用户名和ID信息
            String username = byId.getUsername();
            User user = new User();
            user.setId(userid);
            user.setUsername(username);
//   查询文章对应的标签信息
            Integer tagId = article.getTagId();
            Tag byId1 = tagService.getById(tagId);
//        查询文章的评论数量
            LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Comment::getArticleID,article.getId());
            long count = commentService.count(queryWrapper);
//        赋值信息到传输对象中
            articleDto.setUser(user);
            articleDto.setCommentCount((int) count);
            articleDto.setTag(byId1);
//            如果当前用户未登录，则不可能已经对文章进行点赞
            if(authentication.isAuthenticated()==false)
            {
                articleDto.setIsSupport(0);
            }
            if(authentication.getPrincipal()=="anonymousUser")
            {
                articleDto.setIsSupport(0);
            }
//            否则根据用户ID查询点赞表,查询出记录则当前用户对该文章进行了点赞
            else{
                UserDto principal = (UserDto) authentication.getPrincipal();
                Integer id = principal.getId();
                LambdaQueryWrapper<Support> supportLambdaQueryWrapper = new LambdaQueryWrapper<>();
                supportLambdaQueryWrapper.eq(Support::getArticleId,article.getId());
                supportLambdaQueryWrapper.eq(Support::getUserId,id);
                Support one = supportService.getOne(supportLambdaQueryWrapper);
                if(one==null)
                    articleDto.setIsSupport(0);
                else
                    articleDto.setIsSupport(1);
            }
// 添加到传输集合中
            dtoArrayList.add(articleDto);
        }
        articleDtoPage.setRecords(dtoArrayList);
        return articleDtoPage;
    }

    @Override
    public Page<ArticleDto> getArticleListOrder(Integer page, Integer pageSize, Integer articleType, ArticleDto order) {
        QueryWrapper<Article> articleQueryWrapper = new QueryWrapper<>();
        articleQueryWrapper.eq(articleType!=null,"articleType",articleType);
        articleQueryWrapper.orderBy(order.getSupportCount()!=null,false,"supportCount");
        Page<Article> objectPage = new Page<>(page, pageSize);
        Page<Article> page1 = this.page(objectPage,articleQueryWrapper);
//  文章所属用户信息，文章的评论数，文章对应的标签
        Page<ArticleDto> articleDtoPage =new Page<ArticleDto>();
// 复制除了记录外的所有信息
        BeanUtils.copyProperties(page1,articleDtoPage);
//   对article的分页记录进行处理
        List<Article> records = page1.getRecords();
        ArrayList<ArticleDto> dtoArrayList = new ArrayList<>();
        for(Article article:records){
// 新建文章传输对象
            ArticleDto articleDto = new ArticleDto();
// 将原有信息保存到文章传输对象中
            BeanUtils.copyProperties(article,articleDto);
//查询文章中的用户ID对应的用户信息
            Integer userid = article.getUserid();
            User byId = userService.getById(userid);
// 只传输用户名和ID信息
            String username = byId.getUsername();
            User user = new User();
            user.setId(userid);
            user.setUsername(username);
//   查询文章对应的标签信息
            Integer tagId = article.getTagId();
            Tag byId1 = tagService.getById(tagId);
//        查询文章的评论数量
            LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Comment::getArticleID,article.getId());
            long count = commentService.count(queryWrapper);
//        赋值信息到传输对象中
            articleDto.setUser(user);
            articleDto.setCommentCount((int) count);
            articleDto.setTag(byId1);
//查询当前登录用户是否对文章就行了点赞
// 如果当前用户未登录，则不可能已经对文章进行点赞
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if(!authentication.isAuthenticated())
            {
                articleDto.setIsSupport(0);
            }
            if("anonymousUser".equals(authentication.getPrincipal()))
            {
                articleDto.setIsSupport(0);
            }
//            否则根据用户ID查询点赞表,查询出记录则当前用户对该文章进行了点赞
            else{
                UserDto principal = (UserDto) authentication.getPrincipal();
                Integer id = principal.getId();
                LambdaQueryWrapper<Support> supportLambdaQueryWrapper = new LambdaQueryWrapper<>();
                supportLambdaQueryWrapper.eq(Support::getArticleId,article.getId());
                supportLambdaQueryWrapper.eq(Support::getUserId,id);
                Support one = supportService.getOne(supportLambdaQueryWrapper);
                if(one==null)
                    articleDto.setIsSupport(0);
                else
                    articleDto.setIsSupport(1);
            }
//        添加到传输集合中
            dtoArrayList.add(articleDto);
        }
        articleDtoPage.setRecords(dtoArrayList);
        return articleDtoPage;
    }
//根据文章ID查询文章信息，文章对应的用户信息，文章对应的评论信息
    @Override
    public ArticleDto getArticleDetail(Integer articleId) {
//        根据文章ID查询文章信息
        Article article = this.getById(articleId);
//        文章的用户ID，查询用户信息
        Integer userid = article.getUserid();
        User user = userService.getById(userid);
// 根据文章ID查询对应的评论信息，
        LambdaQueryWrapper<Comment> commentWrapper = new LambdaQueryWrapper<>();
        commentWrapper.eq(Comment::getArticleID,articleId);
        commentWrapper.orderByDesc(Comment::getPublicTime);
        List<Comment> commentList = commentService.list(commentWrapper);
        ArrayList<CommentDto> commentDtos = new ArrayList<>();
//评论信息应该包含user用户信息,子评论信息
        for (Comment comment:commentList) {
            CommentDto commentDto = new CommentDto();
            BeanUtils.copyProperties(comment,commentDto);
            User byId = userService.getById(comment.getUserID());
            commentDto.setUser(byId);
//            添加评论的子评论信息
//          根据评论ID查询childComment表,得到评论的子评论对应ID
            LambdaQueryWrapper<Childcomment> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Childcomment::getCommentID,comment.getId());
            List<Childcomment> list = childcommentService.list(queryWrapper);
//          根据子评论ID查询评论表，查询评论内容以及对应用户信息
//            子评论列表
            if(list!=null) {
//                子评论集合
                ArrayList<ChildListDto> childComments = new ArrayList<>();
                for (Childcomment child : list) {
                    ChildListDto childListDto = new ChildListDto();
//                获取评论ID
                    Integer commentID = child.getChildID();
//                查询子评论表
                    Childlist childlist= childlistService.getById(commentID);
//                    添加子评论信息到子评论传输对象中
                    BeanUtils.copyProperties(childlist, childListDto);
//                查询评论对应的用户信息
                    Integer userID = childlist.getUserID();
//                根据用户ID查询用户信息
                    User byId1 = userService.getById(userID);
//                添加子评论相关信息到子评论集合中
                    childListDto.setUser(byId1);
                    childComments.add(childListDto);
                }
               commentDto.setChildComments(childComments);
            }
            else {
                commentDto.setChildComments(null);
            }
            commentDtos.add(commentDto);
        }
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(article,articleDto);
        articleDto.setUser(user);
        articleDto.setCommentDtos(commentDtos);
        return articleDto;
    }
//通过设置ArticleDTO中的属性来判断查询的条件******************
//分页查询默认一页数目为5个记录
    @Override
    public Page<ArticleDto> getArticleCondition(Integer page, ArticleDto condition) {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
//        根据文章类型（帖子，问答，福利）articleType来查询
        wrapper.eq(condition.getArticleType()!=null,Article::getArticleType,condition.getArticleType());
//        根据文章的点赞数由高到低查询文章集合
        wrapper.orderByDesc(condition.getSupportCount()!=null,Article::getSupportCount);
//        根据标签类型查询文章集合
        wrapper.eq(condition.getTagId()!=null,Article::getTagId,condition.getTagId());
//        根据文章发布时间来查询文章集合,
        wrapper.orderByDesc(condition.getPublicTime()!=null,Article::getPublicTime);
//        根据文章浏览量来查询
//        根据文章标题模糊搜索文章集合
        wrapper.like(condition.getTitle()!=null,Article::getTitle,condition.getTitle());
//根据用户ID查询用户对应的文章集合
        wrapper.eq(condition.getUserid()!=null,Article::getUserid,condition.getUserid());

        Page<Article> objectPage = new Page<>(page,5);
        Page<Article> sourcePage = this.page(objectPage,wrapper);
//  文章所属用户信息，文章的评论数，文章对应的标签
        Page<ArticleDto> articleDtoPage =new Page<>();
// 复制除了记录外的所有信息
        BeanUtils.copyProperties(sourcePage,articleDtoPage);
//   对article的分页记录进行处理,加入如用户信息，点赞信息等数据
//        得到原有的article分页数据
        List<Article> records = sourcePage.getRecords();
        ArrayList<ArticleDto> dtoArrayList = new ArrayList<>();
//        判断当前用户是否登录,用于判断当前登录用户是否给文章点过赞
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        for(Article article:records){
// 新建文章传输对象
            ArticleDto articleDto = new ArticleDto();
//        将原有信息保存到文章传输对象中
            BeanUtils.copyProperties(article,articleDto);
//查询文章中的用户ID对应的用户信息
            Integer userid = article.getUserid();
            User byId = userService.getById(userid);
// 只传输用户名和ID信息
            String username = byId.getUsername();
            User user = new User();
            user.setId(userid);
            user.setUsername(username);
//   查询文章对应的标签信息
            Integer tagId = article.getTagId();
            Tag byId1 = tagService.getById(tagId);
//        查询文章的评论数量
//            查询主评论表
            LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Comment::getArticleID,article.getId());
            long count = commentService.count(queryWrapper);
//            查询子评论表
            LambdaQueryWrapper<Childlist> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(Childlist::getArticleID,article.getId());
            long count1 = childlistService.count(queryWrapper1);
//            判断当前登录用户对文章是否进行了点赞
//            如果当前用户未登录，则不可能已经对文章进行点赞
            if(!authentication.isAuthenticated())
            {
                articleDto.setIsSupport(0);
            }
            if(authentication.getPrincipal()=="anonymousUser")
            {
                articleDto.setIsSupport(0);
            }
//            否则根据用户ID查询点赞表,查询出记录则当前用户对该文章进行了点赞
            else{
                UserDto principal = (UserDto) authentication.getPrincipal();
                Integer id = principal.getId();
                LambdaQueryWrapper<Support> supportLambdaQueryWrapper = new LambdaQueryWrapper<>();
                supportLambdaQueryWrapper.eq(Support::getArticleId,article.getId());
                supportLambdaQueryWrapper.eq(Support::getUserId,id);
                Support one = supportService.getOne(supportLambdaQueryWrapper);
                if(one==null)
                    articleDto.setIsSupport(0);
                else
                    articleDto.setIsSupport(1);
            }
//        赋值信息到传输对象中
//            赋值文章文章所属用户信息到文章传输对象中
            articleDto.setUser(user);
//            查询文章评论评论数量到传输对象中
            articleDto.setCommentCount((int) (count+count1));
//            查询文章对应的标签信息到传输对象中
            articleDto.setTag(byId1);
//        添加到传输集合中
            dtoArrayList.add(articleDto);
        }
        articleDtoPage.setRecords(dtoArrayList);
        return articleDtoPage;
    }


}
